﻿using log4net;
using log4net.Core;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using TransferPost.Beans;
using TransferPost.checkpoints;
using TransferPost.Componts;
using TransferPost.util;

/// <summary>
/// 代码适当重构
/// </summary>
namespace TransferPost.Forms
{
    /// <summary>
    /// 所有SVN检查的交互窗口
    /// ①②③④⑤⑥⑦⑧⑨⑩
    /// </summary>
    [PostFormAttribute(FormName = "SVN提交情况检查", FormNo = "001")]
    public partial class frmSVNCheck : DockContentEx
    {
        private static string URL_SVNIGNORECFG = @"http://friendm.gitee.io/transferpost/";

        public frmSVNCheck()
        {
            InitializeComponent();
        }

        private Dictionary<string, DriveInfo> dicDevicesAndInfos = new Dictionary<string, DriveInfo>();

        /// <summary>
        /// 先临时简单处理，传入父页面
        /// </summary>
        /// <param name="frm"></param>
        public frmSVNCheck(frmMain frm)
        {
            frm_Parent = frm;

            InitializeComponent();
        }

        private void DockFrmMain_Shown(object sender, EventArgs e)
        {
            clbAllDevices.Items.Clear();

            // 初始化磁盘列表，填充，全选
            DriveInfo[] volumes = DriveInfo.GetDrives();

            for (int i = 0; i < volumes.Length; i++)
            {
                this.clbAllDevices.Items.Add(volumes[i].Name);

                this.clbAllDevices.SetItemChecked(i, true);
            }

            this.gridSVNList.AutoGenerateColumns = false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnListSVNDic_Click(object sender, EventArgs e)
        {
            StringBuilder str = new StringBuilder();

            // 重新判断
            DriveInfo[] volumes = DriveInfo.GetDrives();

            // 获取选中的磁盘符号
            dicDevicesAndInfos.Clear();

            if (this.clbAllDevices.CheckedItems.Count > 0)
            {
                str.Append("您选择了扫描：");

                // 填充汇总信息
                for (int i = 0; i < this.clbAllDevices.Items.Count; i++)
                {
                    if (clbAllDevices.GetItemCheckState(i) == CheckState.Checked)
                    {
                        dicDevicesAndInfos.Add(clbAllDevices.Items[i].ToString(), volumes[i]);

                        str.Append(clbAllDevices.Items[i].ToString() + " ");
                    }
                }

                str.Append("扫描将利用USN，但是如果文件过多也将消耗几分钟时间，请耐心等待【Grid出现文件列表】再点【检测SVN状态】！");

                MessageBox.Show(str.ToString());
            }
            else
            {
                MessageBox.Show("请选择需要扫描的磁盘;");
                return;
            }

            //btnListSVNDic.Visible = false;

            var thread_ScanDic = new Thread(() =>
            {
                C_SVNCheck_Point p = new C_SVNCheck_Point();
                p.OnCheckProcessEvent += new DoCheckProcessHandler(Process_Svn);

                if (p.PrepareCheck(dicDevicesAndInfos))
                {
                    RtnBean bean = p.DoCheck(dicDevicesAndInfos);

                    List<SVNCheckBean> lstScanRtn = (List<SVNCheckBean>)bean.par["svn"];

                    OutPutBootmMsg(string.Format("共检测到SVN目录共[{0}]处", lstScanRtn.Count));

                    MsgOutPut.OutSvnGrid(this.gridSVNList, bean);
                }
                else
                {
                    string content = "警告：存在磁盘非NTFS格式或者无法创建USN文件，检查工作无法完全匹配，可以联系ZHZHH5425；";
                    MessageBox.Show(content);
                }
            });

            thread_ScanDic.Start();
        }


        /// <summary>
        /// add by zhzhh at 2019年12月14日 11点47分
        /// 以后多线程同步更新
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="bean"></param>
        private void Process_Svn(MsgBean msg, RtnBean bean)
        {
            if (msg.MsgType != Level.Info)
            {
                MessageBox.Show(msg.msg);
            }

            OutPutBootmMsg(msg.msg);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="msg"></param>
        private void OutPutBootmMsg(string msg)
        {
            PostContext.Instance.MyLogger.Info(msg);

            frm_Parent.AppendText(string.Format("{0} {1}{2}", DateTime.Now.ToString(), msg, System.Environment.NewLine));
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCheckStatus_Click(object sender, EventArgs e)
        {
            if (this.gridSVNList.DataSource == null)
            {
                MessageBox.Show("尚未扫描结束，请等待文件扫描结束。");

                return;
            }

            var thread_CheckSVN = new Thread(() =>
            {
                string str_SVNExePath = Path.Combine(Application.StartupPath, @"svn\svn.exe");

                OutPutBootmMsg(string.Format("默认采用的忽略项：{0}", C_SVNCheck_Point.GetRegIgnores()));

                //  最好是用数据源，先写个吧
                foreach (DataGridViewRow item in this.gridSVNList.Rows)
                {
                    SVNCheckBean bean = (SVNCheckBean)item.DataBoundItem;

                    if (!bean.Selected)
                        continue;

                    string strCurrentPath = bean.path;

                    OutPutBootmMsg(string.Format("开始检测：{0}", strCurrentPath));

                    // 以后再去做异步的
                    using (Process process = new System.Diagnostics.Process())
                    {
                        // 强制刷一下SVN
                        process.StartInfo.FileName = str_SVNExePath;
                        process.StartInfo.WorkingDirectory = strCurrentPath;
                        process.StartInfo.Arguments = " upgrade ";
                        process.StartInfo.UseShellExecute = false;
                        process.StartInfo.CreateNoWindow = true;
                        process.StartInfo.RedirectStandardOutput = true;

                        process.Start();
                        process.WaitForExit();

                        process.StartInfo.FileName = str_SVNExePath;
                        process.StartInfo.WorkingDirectory = strCurrentPath;
                        process.StartInfo.Arguments = " st ";
                        process.StartInfo.UseShellExecute = false;
                        process.StartInfo.CreateNoWindow = true;
                        process.StartInfo.RedirectStandardOutput = true;
                        process.StartInfo.RedirectStandardError = true;

                        process.Start();

                        process.OutputDataReceived += (s, e1) =>
                        {
                            if (e1.Data != null)
                            {
                                // 正确和错误的信息都在这里。
                                string str = e1.Data;

                                PostContext.Instance.MyLogger.Info(str);

                                C_SVNCheck_Point.AnalyOutPut(bean, str);
                            }
                        };


                        process.BeginOutputReadLine();

                        process.BeginErrorReadLine();

                        process.WaitForExit();

                        process.Close();

                        DrawCell(item, bean);
                    }
                }

                OutPutBootmMsg("扫描完毕，双击选中行可以快速打开文件夹，请检查提交情况，再次点击[④判断SVN]");

                MessageBox.Show("扫描完毕");
            });

            thread_CheckSVN.Start();
        }

        private void DrawCell(DataGridViewRow item, SVNCheckBean bean)
        {
            DataGridViewCellStyle style_warning = new DataGridViewCellStyle();
            style_warning.ForeColor = Color.Red;
            style_warning.Font = new Font("宋体", 13f);

            item.Cells[2].Value = bean.modify_count + bean.add_count + bean.del_count + bean.nonversioned_count;

            int i_Ness = bean.necessary_add_count + bean.necessary_del_count + bean.necessary_modify_count + bean.necessary_nonversioned_count;
            item.Cells[3].Value = i_Ness;

            if (i_Ness > 0)
                item.Cells[3].Style = style_warning;
        }

        private void Process_OutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            if (e.Data != null)
            {
                MessageBox.Show(e.Data);
            }
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void gridSVNList_RowStateChanged(object sender, DataGridViewRowStateChangedEventArgs e)
        {
            e.Row.HeaderCell.Value = string.Format("{0}", e.Row.Index + 1);

            //e.Row.Cells[0].Value = "True";
        }

        /// <summary>
        /// 修改本机的SVN忽略项为我统一发布的地址
        /// 
        /// 知识：
        /// 普通的SVN的忽略项都是通过TortoiseSVN-General-Global ignore pattern 配置；
        /// 
        /// 方法：
        /// https://gitee.com/friendm/TransferPost/blob/master/svnignore.txt
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSetIgnore_Click(object sender, EventArgs e)
        {
            //string strIgnores = C_SVNCheck_Point.GetRemotingSVNIgnores();

            //if (strIgnores == "")
            //{
            //    // 默认设置的值
            //    strIgnores = C_SVNCheck_Point.IGN_LST;
            //}

            string strIgnores = C_SVNCheck_Point.IGN_LST;

            C_SVNCheck_Point.SetRegIgnores(strIgnores);

            OutPutBootmMsg(string.Format("已设置忽略项为：{0},{1}", strIgnores, "可以通过SVN右键菜单查看"));

            MessageBox.Show("已设置忽略项为：" + strIgnores);
        }
       

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void gridSVNList_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.RowIndex > -1 && this.gridSVNList.Rows[e.RowIndex].DataBoundItem != null)
            {
                SVNCheckBean bean = (SVNCheckBean)this.gridSVNList.Rows[e.RowIndex].DataBoundItem;
                System.Diagnostics.Process.Start("Explorer.exe", bean.path);
            }

        }
    }
}
